#
# Copyright (C) [2024] Xingyun Integrated Circuit, Inc.
#
# GreenCode was a private technology asset of Xingyun Integrated Circuit， Inc （Confidential）
# Author: Shawn.Tan
# Date: 2025.10.28
#
# History: Initial Version 2025.10.28
#
#
import RandomUtils

from base.ChoicesModifier import ChoicesModifier
from base.Sequence import Sequence
from gpgpu.EnvGPGPU import EnvGPGPU
from gpgpu.GenThreadGPGPU import GenThreadGPGPU
from gpgpu.ModifierUtils import PageFaultModifier


# This test verifies that the PageFaultModifier does not unintentionally induce
# access faults on branch instructions.
class MainSequence(Sequence):
    def generate(self, **kwargs):
        page_fault_mod = PageFaultModifier(self.genThread, self.getGlobalState("AppRegisterWidth"))
        page_fault_mod.apply(**{"All": 1})

        # The PageFaultModifier alters the page size choices, so we need to
        # set the desired values after applying the page fault modifications
        choices_mod = ChoicesModifier(self.genThread)
        satp_info = self.getRegisterInfo("satp", self.getRegisterIndex("satp"))
        if satp_info["Width"] == 32:
            choices_mod.modifyPagingChoices("Page size#4K granule#S#stage 1", {"4K": 1, "4M": 10})
        else:
            choices_mod.modifyPagingChoices(
                "Page size#4K granule#S#stage 1",
                {"4K": 1, "2M": 10, "1G": 10, "512G": 10},
            )

        choices_mod.commitSet()

        instruction_list = ("JAL##CALM", "JALR##CALM")
        for _ in range(RandomUtils.random32(2, 5)):
            self.genInstruction(self.choice(instruction_list))

        page_fault_mod.revert()

        if self.queryExceptionRecordsCount(1) != 0:
            self.error("Unexpected instruction access fault.")


MainSequenceClass = MainSequence
GenThreadClass = GenThreadGPGPU
EnvClass = EnvGPGPU
